/**************************************************************************************************
  Filename:       cent_stream.c
  Revised:        Laura Kassovic @ MbientLab 
  Revision:       1/21/2014

  Description:    Time App service and characteristic discovery routines.

  Copyright 2011 - 2013 Texas Instruments Incorporated. All rights reserved.

**************************************************************************************************/
/*********************************************************************
 * INCLUDES
 */

#include "bcomdef.h"
#include "OSAL.h"
#include "OnBoard.h"
#include "gatt.h"
#include "gatt_uuid.h"
#include "hal_drivers.h"
#include "gattservapp.h"
#include "dataservice.h"
#include "battprofile.h" 
#include "Cent.h"

/*********************************************************************
 * MACROS
 */

// Used to determine the end of CentConfigList[]
#define CENT_CONFIG_MAX      ( sizeof(CentConfigList) / sizeof(uint8) )

/*********************************************************************
 * CONSTANTS
 */
 
// Array of handle cache indexes.  This list determines the
// characteristics that are read or written during configuration.
const uint8 CentConfigList[] =
{
  HDL_DATA_PACK_START,            // Current Data
  HDL_BATT_LEVEL_START,      	  // Battery level
  HDL_DATA_PACK_CCCD,             // New Data CCCD
  HDL_BATT_LEVEL_CCCD,            // Battery level CCCD
  
  // these characteristics are configured at connection setup
  HDL_DATA_ACK,
  HDL_DATA_CTRL,
};

// start index of alert notification control point in config list
#define CENT_DATA_CTRL_START    5

/*********************************************************************
 * TYPEDEFS
 */

/*********************************************************************
 * GLOBAL VARIABLES
 */

/*********************************************************************
 * @fn      timeAppConfigNext()
 *
 * @brief   Perform the characteristic configuration read or
 *          write procedure.
 *
 * @param   state - Configuration state.
 *
 * @return  New configuration state.
 */
uint8 centConfigNext( uint8 state )
{
  attReadReq_t  readReq;
  attWriteReq_t writeReq;
  bool          read;
  
  // Find next non-zero cached handle of interest
  while ( state < CENT_CONFIG_MAX &&
          centHdlCache[CentConfigList[state]] == 0 )
  {
    state++;
  }

  // Return if reached end of list
  if ( state == CENT_CONFIG_MAX )
  {
    dbg("> CENT_CONFIG_CMPL\n");
    return CENT_CONFIG_CMPL;
  }

  // Determine what to do with characteristic
  switch ( CentConfigList[state] )
  {
    // Read these characteristics
    case HDL_DATA_PACK_START:  
    case HDL_BATT_LEVEL_START:
      read = TRUE;
      break;

    // Set notification for these characteristics
    case HDL_DATA_PACK_CCCD:
    case HDL_BATT_LEVEL_CCCD:
      read = FALSE;
      writeReq.len = 2;
      writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY);
      writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY);
      writeReq.sig = 0;
      writeReq.cmd = 0;
      break;

    // Alert notification control point
    case HDL_DATA_CTRL:
      // initialize control point command
      read = FALSE;
      writeReq.len = 1;
      writeReq.value[0] = DATACTRL_OPENREALTIME;
      writeReq.sig = 0;
      writeReq.cmd = 0;

      break;
    case HDL_DATA_ACK:
      break;
    default:
      break;
  }

  // Do a GATT read or write
  if ( read )
  {
    readReq.handle = centHdlCache[CentConfigList[state]];
    GATT_ReadCharValue( centConnHandle, &readReq, centBLETaskId );
  }
  else
  {
    writeReq.handle = centHdlCache[CentConfigList[state]];
    GATT_WriteCharValue( centConnHandle, &writeReq, centBLETaskId );
  }

  return state;
}

/*********************************************************************
 * @fn      CentConfigGattMsg()
   *
 * @brief   Handle GATT messages for characteristic configuration.
 *
 * @param   state - Discovery state.
 * @param   pMsg - GATT message.
 *
 * @return  New configuration state.
 */
uint8 centConfigGattMsg( uint8 state, gattMsgEvent_t *pMsg )
{
  if ( state > CENT_CONFIG_MAX )
  {
    return CENT_CONFIG_CMPL;
  }
  
  if ( (pMsg->method == ATT_READ_RSP || pMsg->method == ATT_WRITE_RSP) &&
       (pMsg->hdr.status == SUCCESS) )
  {
    // Process response
    switch ( CentConfigList[state] )
    {
      case HDL_DATA_PACK_START:
        // Set clock to time read from time server
        dbg( "what th f**k:%s\n",pMsg->msg.readRsp.value );
        break;

      case HDL_BATT_LEVEL_START:
        // Display battery level
        dbg( "Battery%x\n", pMsg->msg.readRsp.value[0] );
        break;

      case HDL_DATA_ACK:
        // Display phone alert status
        dbg( "ACK:%x\n", pMsg->msg.readRsp.value[0]);
        break;

      case HDL_DATA_CTRL:
        // Display ringer state
        dbg( "CTRL DATA: %x\n", pMsg->msg.readRsp.value[0] );
          
        break;

      default:
        break;
    }
  }

  return centConfigNext( state + 1 );
}


/*********************************************************************
 * @fn      centNotiGattMsg
 *
 * @brief   Handle indications and notifications. 
 *
 * @param   pMsg - GATT message.
 *
 * @return  none
 */
void centNotiGattMsg( gattMsgEvent_t *pMsg )
{
  uint8 i;
  
  // Look up the handle in the handle cache
  for ( i = 0; i < HDL_CACHE_LEN; i++ )
  {
    if ( pMsg->msg.handleValueNoti.handle == centHdlCache[i] )
    {
      dbg("recv notfy data %x from:%x\n",pMsg->msg.handleValueNoti.value,pMsg->msg.handleValueNoti.handle);
      break;
    }
  }

  // Perform processing for this handle 
  switch ( i )
  {
    case HDL_DATA_PACK_START:
      // Set clock to time read from time server
      dbg("notify get:");
      for (uint8 uidx = 0; uidx < 13; ++uidx)
      {
      	 dbg("%x,", pMsg->msg.handleValueNoti.value[uidx] );
      }
      dbg("\n");
      break;

    case HDL_BATT_LEVEL_START:
      // Display battery level
      dbg( "Battery%x\n", pMsg->msg.handleValueNoti.value[0] );
      break;

    default:
      break;
  }
  
  // Send confirm for indication
  if ( pMsg->method == ATT_HANDLE_VALUE_IND )
  {
    ATT_HandleValueCfm( pMsg->connHandle );
  }
}